
cap program drop index_maker
program define index_maker
syntax ,  indexname(name) indexlab(string) inputvars(namelist) suffix(name) operation(name) [samplestd(varname) sampleval(numlist) keepstd(name) recenter imputeover(varname) rescale(namelist)]

 if "`operation'"=="sum"   local egenc rowtotal
 if "`operation'"=="mean"  local egenc rowmean


 if "`samplestd'"!=""{
    local samplevals
      foreach n of local sampleval{
        local samplevals  `samplevals', `n'
      }
    local sampledist if inlist(`samplestd' `samplevals')
 }

/**/
local inputlist
foreach x in `inputvars'{

  if "`imputeover'"!=""{
    levelsof `imputeover', local(imputeovervals)
     foreach v of local imputeovervals{
      qui sum `x'_`suffix' if `imputeover'==`v', d
      replace `x'_`suffix' = r(p50) if missing(`x'_`suffix') & `imputeover'==`v'
     }
  }

  cap drop `x'_std_`suffix'
   qui sum `x'_`suffix'    `sampledist'
   qui gen `x'_std_`suffix' = (`x'_`suffix' - r(mean))/r(sd) `sampledist'
   cap label var `x'_std_`suffix' `"`: variable label `x'_`suffix''"'

  if regexm("`rescale'","`x'") == 1 qui replace `x'_std_`suffix' = - `x'_std_`suffix'
  local inputlist `inputlist' `x'_std_`suffix'

  }


  /**/
 qui egen `indexname'_`suffix' = `egenc'(`inputlist') `sampledist'
     la var `indexname'_`suffix' "`indexlab'"

   if "`keepstd'"!="yes"  drop `inputlist'

   if "`recenter'"!=""{
    qui sum `indexname'_`suffix' `sampledist'
    qui replace `indexname'_`suffix' = (`indexname'_`suffix'-r(mean))/r(sd) `sampledist'
   }

end


cap program drop group_mean
program define group_mean
syntax ,  inputvars(namelist) suffixout(name) suffixin(name) id(varname) groupvar(varname) groups(numlist)

    local levels
      foreach n of local groups{
        local levels  `levels', `n'
      }
    local groupsif inlist(`groupvar' `levels')

foreach x in `inputvars'{

    cap qui egen `x'_`suffixout' = mean(`x'_`suffixin') if `groupsif', by(`id')
        cap qui la var `x'_`suffixout' "`: var lab `x'_`suffixin''"
}

end








cap program drop index_cov_maker
program define index_cov_maker
syntax ,  indexname(name) indexlab(string) inputvars(namelist) suffix(name) operation(name) [samplestd(varname) sampleval(numlist)  recenter imputeover(varname) rescale(namelist)]

capture  drop cov_w_*
capture  drop *_cov_sum
capture  drop `indexname'_cov_`suffix'

 if "`operation'"=="sum"   local egenc rowtotal
 if "`operation'"=="mean"  local egenc rowmean


 if "`samplestd'"!=""{
    local samplevals
      foreach n of local sampleval{
        local samplevals  `samplevals', `n'
      }
    local sampledist if inlist(`samplestd' `samplevals')
 }

/**/
local inputlist
foreach x in `inputvars'{

  if "`imputeover'"!=""{
    levelsof `imputeover', local(imputeovervals)
     foreach v of local imputeovervals{
      qui sum `x'_`suffix' if `imputeover'==`v', d
      replace `x'_`suffix' = r(p50) if missing(`x'_`suffix') & `imputeover'==`v'
     }
  }

  cap drop `x'_std_`suffix'
   qui sum `x'_`suffix'    `sampledist'
   qui gen `x'_std_`suffix' = (`x'_`suffix' - r(mean))/r(sd) `sampledist'
   cap label var `x'_std_`suffix' `"`: variable label `x'_`suffix''"'

  if regexm("`rescale'","`x'") == 1 qui replace `x'_std_`suffix' = - `x'_std_`suffix'
  local inputlist `inputlist' `x'_std_`suffix'

  }

 sum `inputlist'

  * Get Covariance Matrix
  corr `inputlist' `sampledist', cov
  matrix a = r(C)

  * Inverse
  matrix b = inv(a)
  local num : word count `inputlist'
  * Multiply by Column Vector of 1's to get row sum
  matrix X1 = J(`num',1,1)
  matrix B1 = b*X1
  matrix list B1

  * Retrieve variable weights
  local i = 0
  local `indexname'_w_sum = 0
  local inputlist_cov
  foreach v in `inputlist' {
    local ++i
    local `indexname'_`i' = B1[`i',1]
  * Total Weight sum
    local `indexname'_w_sum = ``indexname'_w_sum'+ ``indexname'_`i''
  * Product-Sum
    qui gen cov_w_`i' = `v' * ``indexname'_`i''

  if regexm("`rescale'","`v'") == 1 qui replace cov_w_`i' = - cov_w_`i'
  local inputlist_cov `inputlist_cov' cov_w_`i'
  }

  * Sum of Product-Sums
 qui egen `indexname'_cov_sum = `egenc'(`inputlist_cov') `sampledist'

  * Standardize by sum of all weights
  qui gen `indexname'_cov_`suffix' = `indexname'_cov_sum/``indexname'_w_sum'
  la var `indexname'_cov_`suffix' "`indexlab'"


  * Normalize
   if "`recenter'"!=""{
    qui sum `indexname'_cov_`suffix' `sampledist'
    qui replace `indexname'_cov_`suffix' = (`indexname'_cov_`suffix'-r(mean))/r(sd) `sampledist'
  }
  drop `inputlist' `inputlist_cov' `indexname'_cov_sum

end
